﻿#include "thread_lock.h"

using namespace as::thread;
void RWLock::LockRead()
{
	std::unique_lock<std::mutex> ulk(mutex_);
	cond_r_.wait(ulk, [this]()->bool
		{
			return write_flag_ == false && write_cnt_ == 0;
		}
	);
	++read_cnt_;
}

void RWLock::LockWrite()
{
	std::unique_lock<std::mutex> ulk(mutex_);
	++write_cnt_;
	cond_w_.wait(ulk, [this]()->bool
		{
			return read_cnt_ == 0 && write_flag_ == false;
		}
	);
	write_flag_ = true;
}
void RWLock::ReleaseRead()
{
	std::unique_lock<std::mutex> ulk(mutex_);
	if (--read_cnt_ == 0 && write_cnt_ > 0)
	{
		cond_w_.notify_one();
	}
}
void RWLock::ReleaseWrite()
{
	std::unique_lock<std::mutex> ulk(mutex_);
	write_flag_ = false;
	if (--write_cnt_ == 0)
	{
		cond_r_.notify_all();
	}
	else
	{
		cond_w_.notify_one();
	}
}


void SpinLock::lock()
{
	while (flag.test_and_set(std::memory_order_acquire));
}
void SpinLock::unlock() noexcept
{
	flag.clear(std::memory_order_release);
}

bool SpinLock::try_lock() noexcept
{
	return flag.test(std::memory_order_acquire);
}
